package com.example.btclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

	TextView inTextArea = null;
	EditText outTextArea = null;
	Button sendButton = null;
	private final int REQUEST_ENABLE_BT = 1;
	private BluetoothAdapter mBluetoothAdapter = null;
	private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
	private final String macAddress = "00:15:83:15:A3:10";
	private ConnectThread connectThread;
	private ConnectedThread connectedThread;
	private BluetoothDevice mDevice;
	private Handler mHandler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		inTextArea = (TextView) findViewById(R.id.inTextView);
		outTextArea = (EditText) findViewById(R.id.outEditText);
		sendButton = (Button) findViewById(R.id.sendButton);

		//setUpBT();		


		this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if (mBluetoothAdapter == null) {
			// Device does not support Bluetooth
		}

		if (!mBluetoothAdapter.isEnabled()) {
			Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
		}

		mHandler = new MainHandler();

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public void sendMessage(View view){

		InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
		inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
		String out = outTextArea.getText().toString();
		outTextArea.setText("");
		sendButton.requestFocus();
		notifyMessage("outMessage", out);
		
	}




	private void setUpBT(){

		this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if (mBluetoothAdapter == null) {
			// Device does not support Bluetooth
		}

		if (!mBluetoothAdapter.isEnabled()) {
			Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
		}
	}


	public void startConnection(View view){
		notifyMessage("log", "Starting connection...");
		mDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
		connectThread = new ConnectThread(mDevice);
		connectThread.start();
	}
	
	public void closeConnection(View view){
		notifyMessage("log", "Closing connection...");
		connectedThread.cancel();
	}
	
	private void send(String s){
		connectedThread.write(s.getBytes());
	}


	private void manageConnectedSocket(BluetoothSocket socket){
		connectedThread = new ConnectedThread(socket);
		connectedThread.start();
	}



	private class ConnectThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final BluetoothDevice mmDevice;

		public ConnectThread(BluetoothDevice device) {
			// Use a temporary object that is later assigned to mmSocket,
			// because mmSocket is final
			BluetoothSocket tmp = null;
			mmDevice = device;

			// Get a BluetoothSocket to connect with the given BluetoothDevice
			try {
				// MY_UUID is the app's UUID string, also used by the server code

				notifyMessage("log", "Getting the device...");

				tmp = device.createInsecureRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());
				//tmp = device.createRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());

				notifyMessage("log", "Got it");


			} catch (IOException e) { 
				notifyMessage("log", "device not found, abort");
			}
			mmSocket = tmp;
		}

		public void run() {
			// Cancel discovery because it will slow down the connection

			mBluetoothAdapter.cancelDiscovery();

			try {
				// Connect the device through the socket. This will block
				// until it succeeds or throws an exception
				notifyMessage("log", "Connecting to the socket...");
				mmSocket.connect();
				notifyMessage("log", "Connected");

			} catch (IOException connectException) {
				ParcelUuid[] uuids = mmSocket.getRemoteDevice().getUuids();
				String uuid = uuids[0].getUuid().toString();
				notifyMessage("log", "Can't connect to the socket, abort");
				notifyMessage("log", uuid);
				// Unable to connect; close the socket and get out
				try {
					mmSocket.close();
				} catch (IOException closeException) { }
				return;
			}

			// Do work to manage the connection (in a separate thread)

			manageConnectedSocket(mmSocket);

		}


/*		private void notifyMessage(String key, String value){
			Message msg = handler.obtainMessage();
			Bundle b = new Bundle();
			b.putString(key, value);
			msg.setData(b);
			handler.sendMessage(msg);
		}
*/

		/** Will cancel an in-progress connection, and close the socket */
		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) { }
		}
	}



	private class ConnectedThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final InputStream mmInStream;
		private final OutputStream mmOutStream;
		//private Handler handler;

		public ConnectedThread(BluetoothSocket socket) {
			//this.handler = handler;
			mmSocket = socket;
			InputStream tmpIn = null;
			OutputStream tmpOut = null;

			// Get the input and output streams, using temp objects because
			// member streams are final
			try {
				notifyMessage("log", "Getting streams...");
				tmpIn = socket.getInputStream();
				tmpOut = socket.getOutputStream();
				notifyMessage("log", "Gotten");
			} catch (IOException e) { 
				notifyMessage("log", "Unable to get streams.");
			}

			mmInStream = tmpIn;
			mmOutStream = tmpOut;
		}

		public void run() {
			byte[] buffer = new byte[1024];  // buffer store for the stream
			int bytes; // bytes returned from read()

			// Keep listening to the InputStream until an exception occurs
			while (true) {
				try {
					buffer = new byte[1024];
					// Read from the InputStream
					bytes = mmInStream.read(buffer);
					// Send the obtained bytes to the UI activity
					//mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
					String str = new String(buffer);
					notifyMessage("inMessage", str);
				} catch (IOException e) {
					break;
				}
			}
		}

		/* Call this from the main activity to send data to the remote device */
		public void write(byte[] bytes) {
			try {
				mmOutStream.write(bytes);
			} catch (IOException e) { 
				notifyMessage("log", "Unable to send " + bytes.toString());
			}
		}

		/* Call this from the main activity to shutdown the connection */
		public void cancel() {
			try {
				mmSocket.close();
				notifyMessage("log", "Connection closed.");
			} catch (IOException e) { 
				notifyMessage("log", "Unable to close connection.");
			}
		}

/*		private void notifyMessage(String key, String value){
			Message msg = handler.obtainMessage();
			Bundle b = new Bundle();
			b.putString(key, value);
			msg.setData(b);
			handler.sendMessage(msg);
		}*/


	}


	private class MainHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			Bundle bundle = msg.getData();
			if(bundle.containsKey("log")) {
				String value = bundle.getString("log");
				TextView textView = (TextView) findViewById(R.id.inTextView);
				textView.setTextColor(Color.RED);
				textView.append("log: ");
				textView.setTextColor(Color.BLACK);
				textView.append(value + "\n");
			}else if(bundle.containsKey("inMessage")){
				String value = bundle.getString("inMessage");
				TextView textView = (TextView) findViewById(R.id.inTextView);
				textView.setTextColor(Color.GREEN);
				textView.append("in: ");
				textView.setTextColor(Color.BLACK);
				textView.append(value + "\n");				
			}else if(bundle.containsKey("outMessage")){
				String value = bundle.getString("outMessage");
				TextView textView = (TextView) findViewById(R.id.inTextView);
				textView.setTextColor(Color.BLUE);
				textView.append("out :");
				textView.setTextColor(Color.BLACK);
				textView.append(value + "\n");
				send(value);
			}
		}
	}

	
	private void notifyMessage(String key, String value){
		Message msg = mHandler.obtainMessage();
		Bundle b = new Bundle();
		b.putString(key, value);
		msg.setData(b);
		mHandler.sendMessage(msg);
	}
	
}
